파드 속 컨테이너의 장애
개요
컨테이너는 쉽게 휘발될 수 있다.
파드는 기본적으로 스펙에 명시된 restartPolicy
에 맞춰 컨테이너의 장애를 처리한다.
컨테이너의 장애 정의에 대해서는 컨테이너 프로브를 참고한다.
쿠버네티스에서는 이를 보완하기 위해 파드를 두지만, 사실 클러스터의 관점에서는 파드 역시 어느 정도 휘발성이 있는 것으로 취급한다.
이후에 볼 Deployment에서 보면 알 수 있겠지만 파드는 생겼다 줄었다하는 게 원래 존재 방식이다.
재시작 절차
재시작은 일단 다음 정도의 과정을 거친다.
- initial crash
- 처음으로 실패가 발생했을 때
- 쿠버네티스는
restartPolicy
에 정의된 정책을 토대로 동작을 시도한다.
- repeated crashes
- 첫 충돌이 발생한 후 쿠버네티스는 역시 정의된 딜레이 시간에 맞춰 연속적으로 재시작을 시도하게 된다.
- 이때 시간을 점진적으로 늘리면서 재시작 주기를 길게 늘린다.
- 이를 통해 과도하게 재시작을 하는 상황을 막는다.
- CrashLoopBackOff state
- 충돌과 재시작이 지속적으로 반복되고 있다는 것을 의미한다.
- Backoff reset
- 컨테이너가 일정 시간동안 성공적으로 실행되었을 경우
- 쿠버네티스는 재실행 연기 시간을 초기화하고, 이후에 발생한 실패를 첫 실패로 간주한다.
CrashLoopBackOff
이 중 CrashLoopBackOff
상태는 컨테이너 실패에 따라 자주 보게 되는 상태일 것이다.
크룹백은 언제 주로 발생하는가?
- 어플리케이션이 에러를 일으켜 컨테이너가 종료될 때
- 설정 파일이나 환경 변수가 없어서 실행 상의 에러 발생
- 메모리나 cpu가 충분하지 않아 리소스 제한이 걸렸을 때
- 예정된 시간 동안 어플리케이션이 헬스체크를 실패했을 때
- liveness probe에서 실패 상태가 적용될 때
- 등등..
뭐가 많지만, 결국 컨테이너가 제대로 실행되지 않는 상태들이다.
하지만 이 에러를 대응하기 위해서는 다양한 방법을 시도해볼 필요가 있어서 이렇게 세분화한 것이다.
얼마나 이 에러에 대한 질문이 많았으면 공식 문서에도 떡하니 박아놨다.
- 로깅
kubectl logs
를 통해 로그를 확인한다.
- 이벤트 확인
kubectl describe pod
를 통해 리소스나 설정에 관한 힌트를 얻는다.
- 설정 검토
- 환경 변수나 볼륨 마운트, 외부 자원이 전부 제대로 설정되었는지 확인하기
- 리소스 제한 확인
- 수동으로 리소스를 제한할 때 지나치게 적게 리소스를 부여한 것이 아닌지 체크해본다.
- 앱 디버깅
- 앱 자체에서 발생하는 이슈일 수도 있으니 개발자더러 확인하라 시킨다.
- 개발 환경과 배포 환경이 다른 데에서 이슈가 발생할 가능성도 존재한다.
재시작 정책(restartPolicy)
그래서 재시작 정책에는 무엇이 있단 말인가?
- Always
- 종료 후에는 항상 재시작
- 정상 종료여도 무조건 재시작이나, init 컨테이너는 한번만 실행된다.
- OnFailure
- 비정상 종료일 때만 재시작
- Never
- 무조건 재시작하지 않음
- 파드에서 failed 상태가 나는 이유 중 하나.
- T-파드가 failed 뜨는 상황이란에 실험을 진행했다.
- 이게 아니면 파드 자체가 failed 뜨는 일은 잘 없다.
이 정책은 파드 내부의 앱 컨테이너, 초기화 컨테이너에 대해 동작한다.
사이드카 컨테이너는 재시작 정책이 always인 초기화 컨테이너 내부에서 정의되기에 이를 무시한다.
재시작은 항상 같은 노드 내에서 이뤄지는 것이 보장된다.